import VNode from '../vnode/index'
import { prepareRender } from './render'
import { VModel } from './directive/vmodel';
import { VON } from './directive/von';
import { getObjectValue, mergeAttr } from '../utils/ObjectUtils';
import { VFOR } from './directive/vfor';
import { VBind } from './directive/vbind';

/**
 * 给MiniVue添加挂载方法
 * @param {*} MiniVue 
 */
export function initMount(MiniVue) {
    MiniVue.prototype.$mount = function (el) {
        return mount(this, document.getElementById(el))
    }
}

/**
 * 实现mount事件 
 * @param {*} vm 
 * @param {*} el 
 */
function mount(vm, el) {
    // 返回Promise后执行beforeMount钩子
    return new Promise((resolve) => {
        // 构建虚拟Dom
        vm._vnode = constructVnode(vm, el, parent)
        resolve(1)
        // 进行依赖收集
        prepareRender(vm, vm._vnode)
    })
}

/**
 * 构建虚拟dom
 * @param {} vm
 * @param {} el
 * @param {} parent
 */
export function constructVnode(vm, el, parent) {
    let vnode = analysisNodeAttr(vm, el, parent)
    if(!vnode) {
        const tag = el.nodeName
        const text = getNodeText(el)
        const data = {}
        const nodeType = el.nodeType
        const key = ""
        vnode = new VNode(tag, el, [], text, data, parent, nodeType, key)
        if(el.nodeType == 1 && el.getAttribute("env")) { // 元素节点
            // 合并上层存在的局部变量
            vnode.env = mergeAttr(vnode.env, JSON.parse(el.getAttribute("env")))
        } else {
            vnode.env = mergeAttr(vnode.env, parent ? parent.env : {})
        }
    } 
    // 分析V-bind属性
    VBind(vm, vnode)
    // 递归构建子节点
    let childs = vnode.nodeType == 0 ? vnode.parent.ele.childNodes : vnode.ele.childNodes;
    let len = vnode.nodeType == 0 ? vnode.parent.ele.childNodes.length : vnode.ele.childNodes.length

    for (let i = 0 ; i < len ; i ++) {
        let childNodes = constructVnode(vm, childs[i], vnode);
        if (childNodes instanceof VNode) {
            vnode.children.push(childNodes);
        } else {
            vnode.children = vnode.children.concat(childNodes);
        }
    }
    return vnode;
}

/**
 * 解析Node属性值
 * @param {*} vm 
 * @param {*} vnode 
 * @returns 
 */
function analysisNodeAttr(vm, node, parent) {
    let vnode = null;
    if(node.nodeType != 1) return
    let attrList = node.getAttributeNames();
    attrList.forEach((attr)=> {
        if(attr.startsWith("v-model")) {
            VModel(vm, node, node.getAttribute("v-model"));
        }
        if(attr.startsWith("v-on:") || attr.startsWith("@")) {
            let eventName = attr.replace("v-on:", "").replace("@", "")
            const event = getObjectValue(vm, node.getAttribute(attr))
            VON(vm, node, eventName, event)
        }
        if(attr === "v-for") {
            vnode = VFOR(vm, node, parent, node.getAttribute(attr))
        }
    })
    return vnode;
}


/**
 * 获取节点的文本数据（文本节点）
 * @param {*} el 
 */
function getNodeText(el) {
    return el.nodeType === 3 ? el.textContent.trim() : ''
}

